package coreservlets.filters;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashSet;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class BannedAccessFilter implements Filter {
	private static final String REFERER = "Referer";

	private HashSet<String> bannedSiteTable;

	@Override
	public void destroy() {

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		String requestingHost = req.getRemoteHost();
		String referringHost = getReferringHost(req.getHeader(REFERER));
		String bannedSite = null;
		boolean isBanned = false;
		if (bannedSiteTable.contains(requestingHost)) {
			bannedSite = requestingHost;
			isBanned = true;
		} else if (bannedSiteTable.contains(referringHost)) {
			bannedSite = referringHost;
			isBanned = true;
		}
		if (isBanned) {
			showWarning(response, bannedSite);
		} else {
			chain.doFilter(request, response);
		}
	}

	@Override
	public void init(FilterConfig config) throws ServletException {
		bannedSiteTable = new HashSet<String>();
		String bannedSites = config.getInitParameter("bannedSites");
		if (bannedSites == null) {
			return;
		}
		// Split using one or more white spaces
		String[] sites = bannedSites.split("\\s++");
		for (String bannedSite : sites) {
			bannedSiteTable.add(bannedSite);
			System.out.println("Banned " + bannedSite);
		}

	}

	private String getReferringHost(String refererringURLString) {
		try {
			URL referringURL = new URL(refererringURLString);
			return (referringURL.getHost());
		} catch (MalformedURLException mue) { // Malformed or null
			return (null);
		}
	}

	private void showWarning(ServletResponse response, String bannedSite)
			throws ServletException, IOException {
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 "
				+ "Transitional//EN\">\n";
		out.println(docType + "<HTML>\n"
				+ "<HEAD><TITLE>Access Prohibited</TITLE></HEAD>\n"
				+ "<BODY BGCOLOR=\"WHITE\">\n" + "<H1>Access Prohibited</H1>\n"
				+ "Sorry, access from or via " + bannedSite + "\n"
				+ "is not allowed.\n" + "</BODY></HTML>");
	}

}
